package com.yl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yl.common.SnowflakeIdWorker;
import com.yl.constant.Const;
import com.yl.exception.CustomException;
import com.yl.mapper.RoleMapper;
import com.yl.mapper.RoleMenuMapper;
import com.yl.model.dto.RoleDTO;
import com.yl.model.entity.RoleEntity;
import com.yl.model.entity.RoleMenuEntity;
import com.yl.model.entity.RoleMenuEntity;
import com.yl.model.vo.RoleVO;
import com.yl.service.RoleMenuService;
import com.yl.service.RoleService;
import com.yl.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements RoleService {

    @Resource
    private RoleMenuService sysRoleMenuService;

//    @Resource
//    private DeptAspect deptAspect;

    @Resource
    private RoleService sysRoleService;

    @Resource
    private UserService sysUserService;

    @Resource
    private SnowflakeIdWorker idWorker;

    @Resource
    private RoleMapper sysRoleMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public List<RoleEntity> listRolesByUserId(Long userId) {

        List<RoleEntity> sysRoles = this.list(new QueryWrapper<RoleEntity>()
                .inSql("id", "select role_id from t_user_role where user_id = " + userId));

        return sysRoles;
    }

    @Override
    public RoleVO info(Long id) {

        RoleEntity sysRole = this.getById(id);
        RoleVO roleVo = BeanUtil.copyProperties(sysRole, RoleVO.class);
        // 获取角色相关联的菜单id
        List<RoleMenuEntity> roleMenus = sysRoleMenuService.list(new QueryWrapper<RoleMenuEntity>()
                .eq("role_id", id)
                .eq("is_del",true));
        List<Long> menuIds = roleMenus.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        roleVo.setMenuIds(menuIds);
        return roleVo;
    }

    @Override
    public Page<RoleVO> pageList(RoleDTO dto) {



//        List<String> deptList = deptAspect.getDeptList();

        Page<RoleEntity> pageData = sysRoleService.page(new Page<>(dto.getCurrent(), dto.getSize()),
                new QueryWrapper<RoleEntity>()
                        .eq("is_del",false)
                        .like(StrUtil.isNotBlank(dto.getName()), "name", dto.getName())
        );

        //返回数据处理数据组装
        Page<RoleVO> roleVoPage = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
        List<RoleVO> list = pageData.getRecords().stream()
                .map(e -> BeanUtil.copyProperties(e, RoleVO.class))
                .collect(Collectors.toList());
        roleVoPage.setRecords(list);

        return roleVoPage;
    }

    @Override
    public RoleEntity saveObj(RoleEntity entity) {

        entity.setId(idWorker.nextId());
        entity.setCreateTime(new Date());
        entity.setStatus(Const.STATUS_ON);
        entity.setIsDel(false);
        boolean b = sysRoleService.save(entity);
        if (!b) throw new CustomException("新增数据失败");
        return entity;
    }

    @Override
    public RoleDTO updateObj(RoleDTO dto) {

        RoleEntity role = BeanUtil.copyProperties(dto, RoleEntity.class);
        role.setUpdateTime(new Date());
        boolean b = sysRoleService.updateById(role);
        if (!b) throw new CustomException("更新数据失败");
        // 更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(dto.getId());
        return dto;
    }

    @Override
    public Boolean del(Long[] ids) {

        int b = sysRoleMapper.del(ids);
        if (b==0) throw new CustomException("更新数据失败");
        // 缓存同步删除
        Arrays.stream(ids).forEach(id -> {
            // 更新缓存
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });

        return true;
    }

    @Override
    public Long[] perm(Long roleId, Long[] menuIds) {

        List<RoleMenuEntity> sysRoleMenus = Arrays.stream(menuIds)
                .map(menuId -> {
                    RoleMenuEntity roleMenu = new RoleMenuEntity();
                    roleMenu.setMenuId(menuId);
                    roleMenu.setRoleId(roleId);
                    roleMenu.setIs_del(false);
                    return roleMenu;
                })
                .collect(Collectors.toList());



        // 先删除原来的记录，再保存新的
//        sysRoleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role_id", roleId));
        int i = roleMenuMapper.removeRole(roleId);
        if(i==0) throw new CustomException("删除数据失败");

        sysRoleMenuService.saveBatch(sysRoleMenus);

        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);

        return menuIds;
    }
}
